package org.springframework.remoting.jsonrpc.test.contact;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

/**
 * A JPA-based implementation of the Booking Service. Delegates to a JPA entity
 * manager to issue data access calls against the backing repository. The
 * EntityManager reference is provided by the managing container (Spring)
 * automatically.
 */
@Service("contactService")
@Repository
public class JPAContactService implements ContactService {

  private EntityManager em;

  @PersistenceContext
  public void setEntityManager(EntityManager em) {
    this.em = em;
  }

  @Transactional(readOnly = true)
  @SuppressWarnings("unchecked")
  public List<Contact> findContacts(String username) {
    if (username != null) {
      return em.createQuery("select b from Contact b where b.lastName = :username")
          .setParameter("username", username).getResultList();
    } else {
      return null;
    }
  }
  
  @Transactional(readOnly = true)
  @SuppressWarnings("unchecked")
  public List<Contact> allContacts() {
      return em.createQuery("select b from Contact b")
          .getResultList();
  }

  @Transactional(readOnly = true)
  @SuppressWarnings("unchecked")
  public List<Contact> findContacts(SearchCriteria criteria) {
    String pattern = getSearchPattern(criteria);
    return em.createQuery(
        "select h from Hotel h where lower(h.name) like " + pattern + " or lower(h.city) like " + pattern
            + " or lower(h.zip) like " + pattern + " or lower(h.address) like " + pattern).setMaxResults(
        criteria.getPageSize()).setFirstResult(criteria.getPage() * criteria.getPageSize()).getResultList();
  }

  @Transactional(readOnly = true)
  public Contact findContactById(Long id) {
    return em.find(Contact.class, id);
  }

  // helpers

  private String getSearchPattern(SearchCriteria criteria) {
    if (StringUtils.hasText(criteria.getSearchString())) {
      return "'%" + criteria.getSearchString().toLowerCase().replace('*', '%') + "%'";
    } else {
      return "'%'";
    }
  }

  @Transactional(readOnly = false)
  public void saveContact(Contact contact) {
    em.merge(contact);
    
  }
  
  

}
